package com.besall.allbase.common.utils;


import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.util.Log;
import com.besall.allbase.view.activity.tools.AudioListActivity.AudioListActivity;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * Created by alloxuweibin on 2017/12/9.
 */

public class PcmUtils {
    private String TAG = "PcmUtils";
    private  static PcmUtils instant ;
    private AudioListActivity audioListActivity;
    List<Byte> linkedDeque = new ArrayList<>();
    LinkedBlockingDeque<byte[]> linkedBlockingDeque = new LinkedBlockingDeque<>();
    String fileName = System.currentTimeMillis()+"" ;
    private PcmUtils(){

    }

    public static PcmUtils getInstant(){
        if(instant == null){
            instant = new PcmUtils();
        }
        return  instant ;
    }


    public void addData(AudioListActivity contexts , byte[] data){
        audioListActivity = contexts;
        if(data != null){
            if(linkedDeque == null){
                Log.i(TAG , "linkedBlockingDeque == null so instant");
                linkedDeque  = new ArrayList<>();
            }
            Log.i(TAG, "addData: +++++++1");
            linkedBlockingDeque.add(data);
            Log.i(TAG, "addData: +++++++2");

            checkSavePcmLoopThreadAlive();
            Log.i(TAG, "addData: +++++++3");

            for (byte temp : data){
                linkedDeque.add(temp);
            }
            Log.i(TAG, "addData: +++++++4");

            return;
        }
        Log.i(TAG , "addData data == null");
    }

    private void checkSavePcmLoopThreadAlive(){
        if(pcmFileThread == null || !pcmFileThread.isAlive() || pcmFileThread.isInterrupted()){
            pcmFileThread = new Thread(new Runnable() {
                @Override
                public void run() {

                }
            });
            pcmFileThread.start();
        }
    }

    public void resetPcmFile(){
        Log.i(TAG , "resetPcmFile()");
        if(linkedDeque != null){
            linkedDeque.clear();
        }
        stopPlay();
    }

    public boolean play(int type){

        Log.i(TAG , "play()");
        if(linkedDeque == null || linkedDeque.size() == 0){
            Log.i(TAG , "linkedBlockingDeque == null || linkedBlockingDeque.size() == 0");
            return  false ;
        }
        if(pcmPlayer != null){
            Log.i(TAG , "pcmPlayer != null so cancelPlay");
            pcmPlayer.cancelPlay();
        }
        pcmPlayer = new PcmPlayer(type);
        pcmPlayer.start();
        return  true ;
    }

    public void stopPlay(){
        Log.i(TAG , "stopPlay()");
        if(pcmPlayer != null){
            pcmPlayer.cancelPlay();
        }
    }



    Thread pcmFileThread = new Thread();

    PcmPlayer pcmPlayer = new PcmPlayer(0) ;

    class PcmPlayer extends Thread {
        boolean isPlay = false;
        AudioTrack audioRtack;
//采样率
        public PcmPlayer(int type) {
            Log.i(TAG, "PcmPlayer: ++++++++" + type);
            int bufferSize = AudioRecord.getMinBufferSize(16000, type == 0 ? AudioFormat.CHANNEL_CONFIGURATION_MONO : AudioFormat.CHANNEL_IN_STEREO,
                    AudioFormat.ENCODING_PCM_16BIT);
            Log.i(TAG, "frame size = " + bufferSize * 4);
            audioRtack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, type == 0 ? AudioFormat.CHANNEL_CONFIGURATION_MONO : AudioFormat.CHANNEL_IN_STEREO
                    , AudioFormat.ENCODING_PCM_16BIT, bufferSize * 4, AudioTrack.MODE_STREAM);
            audioRtack.play();
        }

        public void cancelPlay() {
            isPlay = false;
            synchronized (audioRtack) {
                if (audioRtack != null && audioRtack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
                    audioRtack.stop();
                    audioRtack.release();
                }
            }
        }

        @Override
        public void run() {
            super.run();
            Log.i(TAG, "PcmPlayer() run++++");
            isPlay = true;
            if (linkedDeque != null) {
                Log.i(TAG, "linkedDeque size++++ = " + linkedDeque.size());
            }
            if (linkedDeque != null && linkedDeque.size() > 0 && isPlay) {
                byte[] datas = new byte[linkedDeque.size()];
                for (int i = 0; i < linkedDeque.size(); i++) {
                    try {
                        datas[i] = linkedDeque.get(i);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                try {
                    Log.i(TAG, "PcmPlayer() run data +++++ " + linkedDeque.size());
                    audioRtack.write(datas, 0, datas.length);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            Log.i(TAG, "PcmPlayer() run done++++++");
            audioListActivity.audiodone();

            isPlay = false;
            synchronized (audioRtack) {
                if (audioRtack != null && audioRtack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
                    audioRtack.stop();
                    audioRtack.release();
                }
            }

        }
    }

}
